package com.xxx.interceptor;

import com.xxx.annotation.MyLogger;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;

/**
 * the class of advance
 *
 * 自定义拦截器
 * <p>
 * .
 *
 * @author little_lunatic
 * @date 2024-06-14
 */
@Slf4j
public class MyLogHandlerInterceptorAdapter extends HandlerInterceptorAdapter {

    private final ThreadLocal<Long> timingThreadLocal = new ThreadLocal<>();

    /**
     * 在处理请求之前进行拦截。
     * 本方法旨在判断处理器方法上是否注解了{@link MyLogger}，以实现日志记录的功能。
     *
     * @param request HTTP请求对象
     * @param response HTTP响应对象
     * @param handler 处理器对象，用于获取实际处理请求的方法
     * @return 是否继续处理请求的标志
     * @throws Exception 如果处理过程中出现异常
     */
    @Override
    public boolean preHandle(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response, Object handler) throws Exception {
        HandlerMethod handlerMethod = null;
        if (handler instanceof HandlerMethod) {
            handlerMethod = (HandlerMethod) handler;
            Method method = handlerMethod.getMethod();
            MyLogger myLogger = method.getAnnotation(MyLogger.class);
            if (myLogger != null) {
                long startTime = System.currentTimeMillis();
                timingThreadLocal.set(startTime);
            }
        }
        return true;
    }


    /**
     * 在处理请求之后，但在渲染视图之前执行。此方法允许对模型和视图进行修改。
     *
     * @param request 本次请求的HttpServletRequest对象
     * @param response 本次请求的HttpServletResponse对象
     * @param handler 处理本次请求的对象，可能是Controller或其他实现Handler接口的对象
     * @param modelAndView 渲染的模型和视图对象，可能为null，表示不进行视图渲染
     * @throws Exception 如果处理过程中发生异常
     */
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        if (handler instanceof HandlerMethod) {
            HandlerMethod handlerMethod = (HandlerMethod) handler;
            Method method = handlerMethod.getMethod();
            MyLogger myLogger = method.getAnnotation(MyLogger.class);
            if (myLogger != null) {
                long startTime = timingThreadLocal.get();
                timingThreadLocal.remove();
                long endTime = System.currentTimeMillis();
                long expendTime = endTime - startTime;
                log.info("功能描述: {}，本次请求的URL：{}，本次请求的参数：{}\n本次请求的耗时为：{}ms",
                        myLogger.desciption(), request.getRequestURI(), request.getQueryString(), expendTime);

            }
        }
    }
}
